package cn.jofei.server.http.filter;

import cn.jofei.common.config.AppProperties;
import cn.jofei.common.netty.message.Message;
import cn.jofei.common.utils.Utils;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.util.concurrent.DefaultPromise;
import io.netty.util.concurrent.Promise;
import javafx.util.Pair;

import java.util.ArrayList;
import java.util.List;

import static cn.jofei.server.interf.ServerQueue.CLIENT_REG_INFO;
import static cn.jofei.server.interf.ServerQueue.REQUEST_QUEUE_NETTY;

/**
 * HttpRequestFilter
 *
 * @author Jofei Bao
 * @version ngbao v1.0.2
 * @date 2022年07月08日 22:55
 */
public interface HttpRequestFilter {
    /**
     * 过滤链列表
     */
    List<HttpRequestFilter> FILTER_LIST = new ArrayList<>();

    //执行过滤
    boolean doFilter(HttpRequest request, ChannelHandlerContext cx) throws Exception;

    String REMOTE_IP = AppProperties.get("server.domain");

    String WWW = "www";

    /**
     * 获取客户端
     *
     * @param httpRequest
     */
    default String getSubdomain(HttpRequest httpRequest) {
        return getSubdomain(getHost(httpRequest));
    }

    default String getHost(HttpRequest httpRequest) {
        String hostAndPortStr;
        if (HttpMethod.CONNECT.equals(httpRequest.method())) {
            // CONNECT 请求以请求行为准
            hostAndPortStr = httpRequest.uri();
        } else {
            hostAndPortStr = httpRequest.headers().get("Host");
        }
        return hostAndPortStr;
    }

    default String getSubdomain(String host) {
        if (Utils.isNull(host)) {
            return WWW;
        }
        if (host.contains(":")) {
            host = host.substring(0, host.indexOf(":"));
        }
        if (Utils.isIp(host)) {
//            log.info("当前通过IP访问，重定向到 www");
            return WWW;
        } else {
            if (host.contains(REMOTE_IP)) {
                String replace = host.replace(REMOTE_IP, "");
                if (Utils.isNull(replace)) {
                    return WWW;
                } else {
                    return replace.replace(".", "");
                }
            } else {
                return host.substring(0, host.indexOf("."));
            }
        }
    }

    static Pair<Message, Promise<Channel>> getChannelPromise(ChannelHandlerContext ctx, String subdomain) {
        Message message = Message.notify(subdomain);

        // 拿到客户端 通信通道
        ChannelHandlerContext context = CLIENT_REG_INFO.get(subdomain);
        if (context != null) {
            // 发起通知
            context.writeAndFlush(message);
            Promise<Channel> promise = new DefaultPromise<>(ctx.channel().eventLoop());
            //添加到 sequenceId -> promise 映射
            REQUEST_QUEUE_NETTY.putIfAbsent(message.getSequenceId(), promise);
            return new Pair<>(message, promise);
        } else {
            return null;
        }
    }
}
